import { getImgUrl } from "@/components/upload/utils/file.ts";
import { download } from "@/components/upload/utils/api.ts";

export const FormMixin = {
  props: {
    contentKey: {
      type: String,
      default: undefined
    },
    // 获取富文本框数据接口函数
    getModel: {
      type: Function,
      default: null
    },
    // 富文本框字段名
    name: {
      type: String,
      default: "content"
    },
    // 根据 文件id 下载文件接口函数
    downloadFn: {
      type: Function,
      default: null
    },
    // 加载完html后进行其他操作
    modelOk: {
      type: Function,
      default: null
    },
    // 是否需要对图片 / 文件通过下载回显
    needToken: {
      type: Boolean,
      default: false
    }
  },
  data: function() {
    return {
      model: {}
    };
  },
  watch: {
    /**
     * 有标识时，如果标识发生变化，需要重新获取数据
     */
    contentKey: {
      handler(val) {
        if (val) {
          this.getModelFn(val);
        }
      },
      immediate: true
    }
  },
  mounted() {
    this.loadModel();
  },
  methods: {
    loadModel() {
      // 没有传contentKey 时加载富文本等数据
      if (this.contentKey) {
        return;
      }
      this.getModelFn();
    },
    /**
     * 根据 contentKey标识 获取富文本框数据
     */
    getModelFn(key) {
      if (!this.getModel) {
        this.$message.warning("请传递'getModel'属性函数");
        return;
      }
      return this.getModel(key)
        .then(model => {
          this.model = model;
          return Promise.resolve();
        })
        .then(() => {
          this.initFile();
          this.loadCustomStyle?.();
          this.modelOk?.();
        });
    },
    /**
     * 获取富文本内容后对图片和文件进行下载
     */
    initFile() {
      if (!this.needToken) {
        return;
      }
      // 下载图片
      const imgs = document.querySelectorAll(".mce-content-body img");
      imgs.forEach(item => {
        if (item.src.startsWith("blob:http")) {
          // 进入此if说明已经下载过图片，不需要重新下载
          return;
        }
        const url = item.src.split("/");
        const id = url[url.length - 1];
        this.downloadFn(id)
          .then(v => getImgUrl(v))
          .then(v => {
            item.src = v;
          });
      });
      // 下载文件
      const files = Array.from(document.querySelectorAll(".mce-content-body a"));
      const downloadFiles = files.filter(item => item.href.includes("download="));
      downloadFiles.forEach(item => {
        item.setAttribute("url", item.href);
        // eslint-disable-next-line no-script-url
        item.href = "javascript:void(0)";
        item.onclick = () => {
          const file = item.getAttribute("url").split("download=")[1];
          const id = file.split(":")[0];
          const filename = file.split(":")[1];
          this.downloadFn(id, false)
            .then(data => {
              download(data, decodeURI(filename));
            })
            .catch(() => {
              this.$message.error("下载失败");
            });
        };
      });
      // 下载视频
      const video = Array.from(document.querySelectorAll(".mce-content-body video"));
      if (video.length > 0) {
        video.forEach(video => {
          video.style.objectFit = "cover";
          const posterId = video.getAttribute("poster");
          if (posterId) {
            // 进入此 if 说明设置了视频封面图片，需要下载回显
            this.downloadFn(posterId)
              .then(v => getImgUrl(v))
              .then(v => {
                video.setAttribute("poster", v);
              });
          }
          if (video.src.startsWith("blob:http")) {
            // 进入此if说明已经下载过视频，不需要重新下载
            return;
          }
          const source = video.querySelector("source");
          if (source.src.includes("download=")) {
            const file = source.src.split("=")[1];
            const id = file.split(":")[0];
            this.downloadFn(id)
              .then(data => {
                const blob = new Blob([data]);
                const blobURL = window.URL.createObjectURL(blob);
                video.src = blobURL;
                video.setAttribute("controlsList", "nodownload");
              });
          }
        });
      }
    }
  }
};

// 用于需要自定义 css 和 js 代码块使用mixin
export const FormCustomStyleMixin = {
  props: {
    // 自定义 css 样式属性字段名
    cssName: {
      type: String,
      default: "cssContent"
    },
    // 自定义js 代码块字段名
    jsName: {
      type: String,
      default: "jsContent"
    }
  },
  beforeDestroy() {
    this.removeStyle();
  },
  methods: {
    /**
     * 对特殊字符进行反转义
     */
    HTMLDecode(str) {
      let temp = document.createElement("div");
      temp.innerHTML = str;
      const output = temp.innerText || temp.textContent;
      temp = null;
      return output;
    },
    /**
     * 富文本框加载完后加载自定义css样式和运行自定义js代码
     */
    loadCustomStyle() {
      const cssContent = this.model[this.cssName];
      const jsContent = this.model[this.jsName];
      this.$nextTick(() => {
        if (jsContent) {
          // 运行自定义JS代码块
          // eslint-disable-next-line no-eval
          eval(this.HTMLDecode(jsContent));
        }
        if (cssContent) {
          // 添加自定义 CSS 样式
          const style = document.createElement("style");
          style.setAttribute("setting", "tinymce");
          style.innerHTML = cssContent;
          document.head.appendChild(style);
        }
      });
    },
    /**
     * 清除掉自定义style
     */
    removeStyle() {
      const settingStyle = Array.from(document.head.querySelectorAll("style")).filter(item => item.getAttribute("setting") === "tinymce");
      if (settingStyle.length > 0) {
        settingStyle.forEach(item => {
          document.head.removeChild(item);
        });
      }
    }
  }
};